﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

//double Division(int len, int time) {
//	if (time == 0) throw invalid_argument("除0错误");
//	return (double)len / (double)time;
//}
//
//void Func() {
//	int* p = new int[10];
//
//	int len, time;
//	cin >> len >> time;
//	cout << Division(len, time) << endl;//如果抛异常，这行之后的语句都不会执行
//
//	delete[] p;//抛异常会导致p未释放
//	cout << "delete[] " << p << endl;
//}
//
//int main() {
//	try {
//		Func();
//	}
//	catch (exception& e) {
//		cout << e.what() << endl;
//	}
//	return 0;
//}
////在 Division 函数中抛出异常，会导致 Func 函数中的 delete[] p 无法执行，从而引发内存泄漏。
////虽然可以在 Func 内部捕获异常、释放内存后重新抛出，但这会导致代码变得复杂且难以维护，特别是当有多个需要释放的资源时。


////使用智能指针解决
//class SmartPtr {
//public:
//	SmartPtr(int* ptr)
//		:_ptr(ptr) {
//	}
//
//	~SmartPtr() {
//		delete[] _ptr;
//		cout << "delete[] " << _ptr << endl;
//	}
//private:
//	int* _ptr;
//};
//double Division(int len, int time) {
//	if (time == 0) throw invalid_argument("除0错误");
//	return (double)len / (double)time;
//}
//void Func() {
//	int* p = new int[10];
//	//用智能指针释放，无论是否抛异常都能正常释放
//	SmartPtr<int> sp(p);
//	int len, time;
//	cin >> len >> time;
//	cout << Division(len, time) << endl;
//}
////不抛异常时的执行流程：Func() 函数结束，sp是栈对象，离开作用域时自动调用 ~SmartPtr()。
////抛异常时的执行流程：由于异常抛出，Func() 的当前执行被中断，栈展开（Stack Unwinding） 开始：
////C++会析构 Func()中的所有栈对象（这里是sp）。sp.~SmartPtr() 被调用，执行 delete[] _ptr，释放内存。
//int main() {
//	try {
//		Func();
//	}
//	catch (exception& e) {
//		cout << e.what() << endl;
//	}
//
//	return 0;
//}


//改为模板
template <class T>
class SmartPtr {
public:
	SmartPtr(T* ptr)
		:_ptr(ptr) {
	}

	~SmartPtr() {
		delete[] _ptr;
		cout << "delete[] " << _ptr << endl;
	}
private:
	T* _ptr;
};

double Division(int len, int time) {
	if (time == 0) throw invalid_argument("除0错误");
	return (double)len / (double)time;
}

void Func() {
	//RAII
	//1.资源获取（Acquisition）：new int[10] 动态分配 10 个 int 的内存空间（资源获取）。
	//2.立即初始化管理对象（Initialization）
	//将原始指针 int* 立即传递给 SmartPtr<int> 的构造函数，由 sp1 接管所有权。
	//3.生命周期绑定
	//sp1 是栈对象，其析构函数会在 Func() 结束时（无论正常返回或异常）自动调用，释放 int[10]。
	SmartPtr<int> sp1(new int[10]);
	SmartPtr<double> sp2(new double[10]);
	int len, time;
	cin >> len >> time;
	cout << Division(len, time) << endl;
}

int main() {
	try {
		Func();
	}
	catch (exception& e) {
		cout << e.what() << endl;
	}

	return 0;
}